Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add tokio-retry crate to retry failed requests #8

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

antonispoulakis
Copy link

@antonispoulakis antonispoulakis commented Jun 27, 2022

Added tokio-retry crate with a with_retry helper to retry failed requests. This is useful since request timeouts seem to be happening even with a high timeout value.

Copy link
Member

@operutka operutka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi. Thank you for your PR.

At first, please take a look the LogglyClient::send() method (https://github.com/angelcam/rust-slog-loggly/blob/master/src/client.rs#L131). This method will keep trying to send a given message indefinitely if there is an error, so the code that you'd like to add will only retry each individual attempt multiple times. This makes no sense.

If you'd like to change the default behavior from infinite number of attempts to a limited number of attempts with some backoff function, I don't have any problem with that. You'll just need to modify the send method.

Please, make sure that you use cargo fmt and cargo clippy before you commit any code and make sure that all your functions/methods are properly documented.

pub async fn with_retry<A, F, R, E>(ms: Option<u64>, attempts: Option<usize>, action: A) -> Result<R, E>
where
A: FnMut() -> F,
E: std::fmt::Display,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bound probably isn't necessary. The tokio-retry crate does not require the error type to implement Display and the function itself does not format/display the error.

time::Duration
};

fn retry_strategy(ms: u64, attempts: usize) -> Take<Map<FibonacciBackoff, fn(Duration) -> Duration>>{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fn retry_strategy(ms: u64, attempts: usize) -> Take<Map<FibonacciBackoff, fn(Duration) -> Duration>>{
fn retry_strategy(base: Duration, attempts: usize) -> impl Iterator<Item = Duration> {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function itself probably isn't necessary. It's very simple and it's used only once. It only bloats the code. I'd put the contents directly into with_retry.

};

fn retry_strategy(ms: u64, attempts: usize) -> Take<Map<FibonacciBackoff, fn(Duration) -> Duration>>{
FibonacciBackoff::from_millis(ms)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
FibonacciBackoff::from_millis(ms)
FibonacciBackoff::from_millis(base.as_millis() as u64)


fn retry_strategy(ms: u64, attempts: usize) -> Take<Map<FibonacciBackoff, fn(Duration) -> Duration>>{
FibonacciBackoff::from_millis(ms)
.map(jitter as fn(Duration) -> Duration)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.map(jitter as fn(Duration) -> Duration)
.map(jitter)

}


pub async fn with_retry<A, F, R, E>(ms: Option<u64>, attempts: Option<usize>, action: A) -> Result<R, E>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub async fn with_retry<A, F, R, E>(ms: Option<u64>, attempts: Option<usize>, action: A) -> Result<R, E>
pub async fn with_retry<A, F, R, E>(base_delay: Duration, attempts: usize, action: A) -> Result<R, E>

Let's put the defaults into the client module as constants and make them configurable using LogglyClientBuilder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants